import math
from collections import Counter

def calculate_entropy(filepath):
    """
    计算二进制文件的香农熵
    
    参数:
        filepath: 文件路径
    
    返回:
        entropy: 熵值 (0-8 bits)
    """
    try:
        # 读取文件
        with open(filepath, 'rb') as f:
            data = f.read()
        
        if not data:
            return 0
        
        # 统计每个字节出现的次数
        counter = Counter(data)
        length = len(data)
        
        # 计算熵
        entropy = 0
        for count in counter.values():
            probability = count / length
            entropy -= probability * math.log2(probability)
        
        return entropy
    
    except FileNotFoundError:
        print(f"错误: 文件 '{filepath}' 不存在")
        return None
    except Exception as e:
        print(f"错误: {e}")
        return None


def analyze_file(filepath):
    """分析文件并给出判断"""
    print(f"正在分析文件: {filepath}")
    print("-" * 50)
    
    entropy = calculate_entropy(filepath)
    
    if entropy is None:
        return
    
    print(f"熵值: {entropy:.6f} bits")
    print(f"熵值百分比: {(entropy/8)*100:.2f}%")
    print("-" * 50)
    
    # 判断
    if entropy > 7.9:
        print("判断: 极高熵 - 很可能是强加密数据")
    elif entropy > 7.5:
        print("判断: 高熵 - 可能是加密或高质量压缩数据")
    elif entropy > 6.5:
        print("判断: 较高熵 - 可能是压缩数据")
    elif entropy > 4:
        print("判断: 中等熵 - 可能是未加密的二进制数据")
    else:
        print("判断: 低熵 - 可能是文本或高度结构化数据")


# 使用示例
if __name__ == "__main__":
    # 方法1: 直接指定文件路径
    filepath = "main"  # 替换为你的文件路径
    analyze_file(filepath)
    
    # 方法2: 从命令行参数获取
    # import sys
    # if len(sys.argv) > 1:
    #     filepath = sys.argv[1]
    #     analyze_file(filepath)
    # else:
    #     print("用法: python entropy.py <文件路径>")